package com.teamblueplus.comicmaker;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;

import com.teamblueplus.R;
import com.teamblueplus.brush.ColorPickerDialog;

import com.teamblueplus.websearch.GoogleSearchAPIActivity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;

import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


/**
 * ComicMaker is the main activity for making comic
 * @author qui
 *
 */
public class ComicMaker extends Activity implements OnClickListener,
		ColorPickerDialog.OnColorChangedListener {

	ComicSurfaceView mySurfaceView;
	ComicDrawThread myThread;
	Button bMoveFront, bDelete, bAddText, bAddImage, bAddBubble, bSave, bBrush, bAddDivider;

	private String selectedImagePath;
	private AlertDialog addImageDialog, addBubbleDialog, addTextDialog, addDividerDialog;

	private final static int SELECT_GALLERY = 1, SELECT_DEFAULT = 2,
			SELECT_CAMERA = 3, SELECT_WEB = 4, EDITOR_GALLERY = 5,
			EDITOR_DEFAULT = 6;

	// path of image taken from camera
	private Uri mImageCaptureUri;

	Bitmap bubble1, bubble2;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.test_comic_making);
		
		//if comicmaker is called from viewcomicActivity
		String backgroundImgPath = this.getIntent().getStringExtra("path");
		Log.d("h2", "bakcgoirnd:::"+ backgroundImgPath);
		

		// get handles to the GameView from XML and the Tutorial thread.
		mySurfaceView = (ComicSurfaceView) findViewById(R.id.myView);
		myThread = mySurfaceView.getThread();
		
		//set the background image if this activity is called from viewComic
		if(backgroundImgPath!=null)
		    mySurfaceView.setBackgroundImage(backgroundImgPath, true);

		// button listeners
		bDelete = (Button) findViewById(R.id.bDelete);
		bDelete.setOnClickListener(this);
		
		bMoveFront = (Button) findViewById(R.id.bMoveFront);
		bMoveFront.setOnClickListener(this);

		bAddImage = (Button) findViewById(R.id.bAddImage);
		bAddImage.setOnClickListener(this);

		bAddBubble = (Button) findViewById(R.id.bAddBubble);
		bAddBubble.setOnClickListener(this);

		bAddText = (Button) findViewById(R.id.bAddText);
		bAddText.setOnClickListener(this);
		
		bAddDivider = (Button) findViewById(R.id.bAddDivider);
		bAddDivider.setOnClickListener(this);

		bSave = (Button) findViewById(R.id.bSave);
		bSave.setOnClickListener(this);

		bBrush = (Button) findViewById(R.id.bBrush);
		bBrush.setOnClickListener(this);

		// creates the menu for add button
		createCustomDialog();
		createBubbleDialog();
		createTextDialog();
		createDividerDialog();

	}

	@Override
	protected void onPause() {
		Toast.makeText(getApplicationContext(), "pausing ", Toast.LENGTH_SHORT)
				.show();
		super.onPause();
		mySurfaceView.pause();
	}

	@Override
	protected void onResume() {
		Toast.makeText(getApplicationContext(), "resuming", Toast.LENGTH_SHORT)
				.show();
		super.onResume();
		mySurfaceView.resume();
		myThread = mySurfaceView.getThread();
	}

	@Override
	public void onClick(View v) {

		switch (v.getId()) {

		case R.id.bAddImage:
			addImageDialog.show();

			break;

		case R.id.bAddBubble:
			addBubbleDialog.show();
			break;

		case R.id.bAddText:
			addTextDialog.show();

			break;
			
		case R.id.bAddDivider:
			addDividerDialog.show();

			break;

		case R.id.bSave:
			mySurfaceView.getThread().isDrawing = false;
			final Handler saveHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					setResult(RESULT_OK);
					mySurfaceView.pause();
					finish();
				}
			};

			AlertDialog.Builder alert = new AlertDialog.Builder(this);
			alert.setTitle("Saving Image");
			alert.setMessage("Type in file name");
			// Set an EditText view to get user input
			final EditText input = new EditText(this);
			alert.setView(input);
			alert.setPositiveButton("Ok",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							new ExportBitmapToFile(getApplicationContext(),
									saveHandler,
									mySurfaceView.getThread().mBitmap, input
											.getText().toString() + ".jpg")
									.execute();
						}
					});
			alert.setNegativeButton("Cancel",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							// Canceled.
						}
					});
			alert.show();
			// doSaveImage();

			break;

		case R.id.bBrush:
			mySurfaceView.toggleBrush();

			break;

		case R.id.bDelete:
			this.deleteLayer();

			break;
			
		case R.id.bMoveFront:
			this.moveToFont();
			break;
		}
	}

	public void createCustomDialog() {
		final String[] items = new String[] { "Default Objects",
				"Select from gallery", "Select from Camera", "Search the Web" };
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.select_dialog_item, items);
		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		builder.setTitle("Select Image");
		builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				// default object
				if (item == 0) {
					Intent intent = new Intent(ComicMaker.this,
							AddDefaultObject.class);
					ComicMaker.this.startActivityForResult(intent,
							SELECT_DEFAULT);
				}
				// select from gallery
				else if (item == 1) {
					Intent intent = new Intent();
					intent.setType("image/*");
					intent.setAction(Intent.ACTION_GET_CONTENT);
					startActivityForResult(
							Intent.createChooser(intent, "Select Picture"),
							SELECT_GALLERY);
				}
				// select from camera
				else if (item == 2) {
					Intent intent = new Intent(
							android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

					mImageCaptureUri = Uri.fromFile(new File(Environment
							.getExternalStorageDirectory(), "tmp_avatar_"
							+ String.valueOf(System.currentTimeMillis())
							+ ".jpg"));

					intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
							mImageCaptureUri);

					try {
						intent.putExtra("return-data", true);

						startActivityForResult(intent, SELECT_CAMERA);
					} catch (ActivityNotFoundException e) {
						e.printStackTrace();
					}

				}
				// search the web
				else if (item == 3) {
					Intent intent = new Intent(ComicMaker.this,
							GoogleSearchAPIActivity.class);
					ComicMaker.this.startActivityForResult(intent,
							SELECT_WEB);
				}
			}
		});

		addImageDialog = builder.create();

	}

	// get image
	public void onActivityResult(int requestCode, int resultCode, Intent data) {

		
		if (resultCode == RESULT_OK) {
			Log.d("h2", "onActivityResult");
			if (requestCode == SELECT_GALLERY) {

				Uri selectedImageUri = data.getData();

				selectedImagePath = this.getRealPathFromURI(selectedImageUri);

				// go to image editor
				Intent myIntent = new Intent(ComicMaker.this,
						ImageEditorMakingActivity.class);

				myIntent.putExtra("path", selectedImagePath);

				Log.d("h2", "gallerySelectedPATH::" + selectedImagePath);
				myIntent.putExtra("gallery", true);
				ComicMaker.this.startActivityForResult(myIntent,
						EDITOR_DEFAULT);

			} else if (requestCode == SELECT_WEB) {
				String path = data.getExtras().getString("path");
				if (path != null) {

					selectedImagePath = Environment
							.getExternalStorageDirectory().getAbsolutePath()
							+ "/dimages/" + path;

					// go to image editor
					Intent myIntent = new Intent(ComicMaker.this,
							ImageEditorMakingActivity.class);

					myIntent.putExtra("path", selectedImagePath);
					ComicMaker.this.startActivityForResult(myIntent,
							EDITOR_DEFAULT);
				}
			} else if (requestCode == SELECT_DEFAULT) {
				selectedImagePath = data.getExtras().getString("path");

				// go to image editor
				Intent myIntent = new Intent(ComicMaker.this,
						ImageEditorMakingActivity.class);

				myIntent.putExtra("path", selectedImagePath);
				ComicMaker.this.startActivityForResult(myIntent,
						EDITOR_DEFAULT);

			} else if (requestCode == SELECT_CAMERA) {

				selectedImagePath = this
						.getRealPathFromURI(this.mImageCaptureUri);

				Log.d("h2", "realpath::" + selectedImagePath);

				// go to image editor
				Intent myIntent = new Intent(ComicMaker.this,
						ImageEditorMakingActivity.class);

				myIntent.putExtra("path", selectedImagePath);
				myIntent.putExtra("gallery", true);
				ComicMaker.this.startActivityForResult(myIntent,
						EDITOR_DEFAULT);
			}
			// return from the editor
			else if (requestCode == EDITOR_DEFAULT) {
				Log.d("h2", "retrun from editor_default");
				if (selectedImagePath != null) {
					Log.d("h2", "DEFAULT_OBJECT::" + selectedImagePath);

					myThread.addImage(selectedImagePath);

				}
			}
		}

	}

	// get the real path of the image from gallery
	// http://stackoverflow.com/questions/11591825/how-to-get-image-path-just-captured-from-camera
	public String getRealPathFromURI(Uri contentUri) {
		try {
			String[] proj = { MediaStore.Images.Media.DATA };
			Cursor cursor = managedQuery(contentUri, proj, null, null, null);
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			return cursor.getString(column_index);
		} catch (Exception e) {
			return contentUri.getPath();
		}
	}

	private class ExportBitmapToFile extends AsyncTask<Intent, Void, Boolean> {
		private Context mContext;
		private Handler mHandler;
		private Bitmap nBitmap;
		private String fileName;

		public ExportBitmapToFile(Context con, Handler handler, Bitmap bitmap,
				String fname) {
			mContext = con;
			nBitmap = bitmap;
			mHandler = handler;
			fileName = fname;
		}

		@Override
		protected Boolean doInBackground(Intent... arg0) {
			try {
				File sdCard = Environment.getExternalStorageDirectory();
				File FINISH_COMIC_PATH = new File(sdCard.getAbsolutePath()
						+ "/ComicComicOutput/");

				// check if folder output exists
				if (!FINISH_COMIC_PATH.exists()) {
					FINISH_COMIC_PATH.mkdirs();
				}

				File output = new File(FINISH_COMIC_PATH, fileName);

				final FileOutputStream out = new FileOutputStream(output);
				nBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
				out.flush();
				out.close();
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
			// mHandler.post(completeRunnable);
			return false;
		}

		@Override
		protected void onPostExecute(Boolean bool) {
			super.onPostExecute(bool);
			if (bool) {
				mHandler.sendEmptyMessage(1);
			}
		}
	}


	// text select list
	private void createTextDialog() {
			final String[] items = new String[] { "Small Text",
					"Medium Text", "Big Text",};
			ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
					android.R.layout.select_dialog_item, items);
			AlertDialog.Builder builder = new AlertDialog.Builder(this);

			builder.setTitle("Select Bubble Style");
			builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int item) {
					// small font
					if (item == 0) {
						addText(0);
					}
					// medium font
					else if (item == 1) {
						addText(1);
					}
					// big font
					else if (item == 2) {
						addText(2);
					}
				}
			});

			addTextDialog = builder.create();
	}
	
	private void addText(final int type) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);

		alert.setTitle("Add Text Overlay");
		alert.setMessage("Enter your message");

		// Set an EditText view to get user input
		final EditText input = new EditText(this);

		alert.setView(input);

		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String value = input.getText().toString();

				myThread.addText(type, value);
			}
		});

		alert.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						// Canceled.
					}
				});

		alert.show();
	}
	
	

	// bubble select list
	public void createBubbleDialog() {
		final String[] items = new String[] { "Square Bubble Left",
				"Square Bubble Right", "Round Bubble Left",
				"Round Bubble Right" };
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.select_dialog_item, items);
		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		builder.setTitle("Select Bubble Style");
		builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				// square left
				if (item == 0) {
					addBubble(0);
				}
				// square right
				else if (item == 1) {
					addBubble(1);
				}
				// round left
				else if (item == 2) {
					addBubble(2);
				}
				// round right
				else if (item == 3) {
					addBubble(3);
				}
			}
		});

		addBubbleDialog = builder.create();

	}
	
	// when +bubble is clicked
	private void addBubble(final int style) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);

		alert.setTitle("Add Text Box");
		alert.setMessage("Enter your message");

		// Set an EditText view to get user input
		final EditText input = new EditText(this);

		alert.setView(input);

		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String value = input.getText().toString();

				myThread.addBubble(style, value);
			}
		});

		alert.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						// Canceled.
					}
				});

		alert.show();
	}
	

	// bubble select list
	public void createDividerDialog() {
		final String[] items = new String[] { "Vertical Divider",
				"Horizontal Divider"};
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.select_dialog_item, items);
		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		builder.setTitle("Select Divider");
		builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				// square left
				if (item == 0) {
					myThread.addDivider(0);
				}
				// square right
				else if (item == 1) {
					myThread.addDivider(1);
				}
			}
		});

		addDividerDialog = builder.create();

	}
	
	
	/*
	 * Call thread to delete selected layer 
	 */
	private void deleteLayer(){
		myThread.deleteLayer();
	}
	
	/*
	 * Call thread to move selected layer to front
	 */
	private void moveToFont() {
		myThread.moveToFront();
	}
	

	// for brush functionality, menu settings
	private static final int COLOR_MENU_ID = Menu.FIRST;
	private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
	private static final int BLUR_MENU_ID = Menu.FIRST + 2;
	private static final int ERASE_MENU_ID = Menu.FIRST + 3;
	private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
	private static final int UNDO_MENU_ID = Menu.FIRST + 5;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
		menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
		menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
		menu.add(0, UNDO_MENU_ID, 0, "Undo").setShortcut('6', 'u');
//		menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
//		menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');

		/****
		 * Is this the mechanism to extend with filter effects? Intent intent =
		 * new Intent(null, getIntent().getData());
		 * intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
		 * menu.addIntentOptions( Menu.ALTERNATIVE, 0, new ComponentName(this,
		 * NotesList.class), null, intent, 0, null);
		 *****/
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		mySurfaceView.brush2.mPaint.setXfermode(null);
		mySurfaceView.brush2.mPaint.setAlpha(0xFF);

		switch (item.getItemId()) {
		case UNDO_MENU_ID:
			this.mySurfaceView.undoBrush();
			break;
		case COLOR_MENU_ID:
			new ColorPickerDialog(this, this,
					mySurfaceView.brush2.mPaint.getColor()).show();
			return true;
		case EMBOSS_MENU_ID:
			if (mySurfaceView.brush2.mPaint.getMaskFilter() != mySurfaceView.brush2.mEmboss) {
				mySurfaceView.brush2.mPaint
						.setMaskFilter(mySurfaceView.brush2.mEmboss);
			} else {
				mySurfaceView.brush2.mPaint.setMaskFilter(null);
			}
			return true;
		case BLUR_MENU_ID:
			if (mySurfaceView.brush2.mPaint.getMaskFilter() != mySurfaceView.brush2.mBlur) {
				mySurfaceView.brush2.mPaint
						.setMaskFilter(mySurfaceView.brush2.mBlur);
			} else {
				mySurfaceView.brush2.mPaint.setMaskFilter(null);
			}
			return true;
		case ERASE_MENU_ID:
			mySurfaceView.brush2.mPaint.setXfermode(new PorterDuffXfermode(
					PorterDuff.Mode.CLEAR));
			return true;
		case SRCATOP_MENU_ID:
			mySurfaceView.brush2.mPaint.setXfermode(new PorterDuffXfermode(
					PorterDuff.Mode.SRC_ATOP));
			mySurfaceView.brush2.mPaint.setAlpha(0x80);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void colorChanged(int color) {
		mySurfaceView.brush2.mPaint.setColor(color);

	}

}